﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;

namespace UniversalUpdater
{
    class UpdaterFunctions
    {
        private Version _InstalledVersion;
        private string _AppUpdateUrl;
        private Version _CurrentVersion;
        private string _AppWebPage;
        private string _DownloadLink;
        private string tempPath = Path.GetTempPath();
        private string fileName;
        private UpdaterForm form;
        private WebClient webClient;

        /// <summary>
        /// Nainstalovaná verze
        /// </summary>
        public Version InstalledVersion
        {
            get { return _InstalledVersion; }
        }
        /// <summary>
        /// Stránka, ze které se vyparsují podrobnosti -> současná verze, web aplikace a link ke stažení
        /// </summary>
        public string AppUpdateUrl
        {
            get { return _AppUpdateUrl; }
        }
        /// <summary>
        /// Současná verze aplikace
        /// </summary>
        public Version CurrentVersion
        {
            get { return _CurrentVersion; }
        }
        /// <summary>
        /// Web aplikace
        /// </summary>
        public string AppWebPage
        {
            get { return _AppWebPage; }
        }
        /// <summary>
        /// Link ke stažení současné verze
        /// </summary>
        public string DownloadLink
        {
            get { return _DownloadLink; }
        }



        public UpdaterFunctions(UpdaterForm form, Version InstalledVersion, string AppUpdateUrl)
        {
            webClient = new WebClient();
            this.form = form;
            _InstalledVersion = InstalledVersion;
            _AppUpdateUrl = AppUpdateUrl;

            webClient.DownloadProgressChanged += webClient_DownloadProgressChanged;
            webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;
        }

        /// <summary>
        /// If update exists will return true else false. If error occurs throw an exception
        /// </summary>
        /// <returns></returns>
        public bool CheckForUpdate(bool IsXML = false)
        {
            try
            {
                if (!IsXML)
                {
                    WebRequest request = WebRequest.Create(AppUpdateUrl);
                    WebResponse response = request.GetResponse();
                    StreamReader reader = new StreamReader(response.GetResponseStream());

                    _CurrentVersion = new Version(reader.ReadLine());
                    _AppWebPage = reader.ReadLine();
                    _DownloadLink = reader.ReadLine();
                }
                else
                {
                    XmlReaderSettings settings = new XmlReaderSettings();
                    settings.IgnoreWhitespace = true;
                    settings.IgnoreComments = true;
                    settings.ProhibitDtd = false;
                    settings.XmlResolver = null;

                    string element = "";
                    using (XmlReader reader = XmlReader.Create(AppUpdateUrl, settings))
                    {
                        while (reader.Read())
                        {
                            switch (reader.NodeType)
                            {
                                case XmlNodeType.Element:
                                    element = reader.Name;
                                    break;

                                case XmlNodeType.Text:
                                    if (element == "CurrentVersion") { _CurrentVersion = new Version(reader.Value); }
                                    if (element == "AppWebPage") { _AppWebPage = reader.Value; }
                                    if (element == "DownloadLink") { _DownloadLink = reader.Value; }
                                    break;
                            }
                        }
                        reader.Close();
                    }
                }

                webClient.OpenRead(DownloadLink);
                fileName = new System.Net.Mime.ContentDisposition(webClient.ResponseHeaders["content-disposition"]).FileName;

                return CurrentVersion > InstalledVersion;
            }
            catch
            {
                throw new Exception("Cannot contact update server.");
            }
        }

        /// <summary>
        /// Stáhnout soubor - do %temp%
        /// </summary>
        public void DownloadFile()
        {
            if (String.IsNullOrEmpty(DownloadLink))
                throw new Exception("No download link");

            webClient.DownloadFileAsync(new Uri(DownloadLink), tempPath + fileName);
        }

        public void CancelDownload()
        {
            webClient.CancelAsync();
        }

        private void webClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {
                System.Diagnostics.Process.Start(tempPath + fileName);
                form.Close();
            }
        }

        private void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            form.DownloadProgress.Value = e.ProgressPercentage;
            form.Text = e.ProgressPercentage.ToString() + "%";
        }

    }
}
